import Konva from "konva";
import { Draw } from "../../../Draw/Draw";
import { parseLinePoints } from "../../../Utils";
import { IKonva } from "../../../Interface/IKonva";

/**
 * 线段控制点的移动事件
 *  1. 线段 points 是基于 x y 的偏移量！！！！
 *  2. 控制点移动过程中，还需要判断是否吸附于其他图形
 * @param e
 * @param draw
 * @returns
 */
export function lineControlDragMove(e: IKonva.Event, draw: Draw) {
  const layer = draw.getLayer();
  if (!layer) return;

  // 获取当前控制点
  const control = <Konva.Circle>e.currentTarget;

  // 获取直线
  const line = <Konva.Line>layer.findOne("#" + control.attrs.pid);
  if (!line) return;

  // 解析当前控制点的最新坐标
  const { x, y } = control.position();

  updatePoints(line, control, x, y);

  lineAdsorb(line, control, draw);
}

/**
 * 执行更新 line points
 */
function updatePoints(
  line: Konva.Line,
  control: Konva.Circle,
  x: number,
  y: number
) {
  const lx = line.x();
  const ly = line.y();
  // 解析当前控制点长度
  const controlArr = parseLinePoints(line?.attrs.points);

  // 解析当前控制点的类型 controlIndex 识别起点、重点 不同的更新 points
  const controlIndex = control.attrs.controlIndex;

  /**
   * 直接修改对应 index 的值 即可
   * [0,0,1,1,5,5]
   * 解析二维数组后:
   *  [0,0] => index=0
   *  [1,1] => index=1
   *  [5,5] => index=2
   * 更新时，直接取二维数组剩余数据，修改 index 数据，赋值给 points
   */
  const newPoints: number[] = [];
  controlArr.forEach((item, index) => {
    if (index === controlIndex) {
      newPoints.push(x - lx, y - ly);
    } else {
      newPoints.push(...item);
    }
  });
  line.points(newPoints);
}

/**
 * 控制直线吸附
 */
function lineAdsorb(line: Konva.Line, control: Konva.Circle, draw: Draw) {
  // 1. 先获取当前 control Index
  const { controlIndex, x, y } = control.attrs;

  // 2. 解析当前的 controlArray
  const controlArray = parseLinePoints(line.attrs.points);

  // 3. 控制仅 首尾两个点能吸附
  if (controlIndex !== 0 && controlIndex !== controlArray.length - 1) return;

  const stage = draw.getStage();

  const OFFSET = 10;

  const positionCache: IKonva.LinePositionCache[] = stage.attrs.positionCache;

  const shape = positionCache.find((pos) => {
    // 判断当前位置 x y 是否与 当前 shape 的四个位置相同（可吸附关键 offset）
    return Math.abs(pos.x - x) < OFFSET && Math.abs(pos.y - y) < OFFSET;
  });

  // 判断当前直线是否存在  startShape endShape

  if (controlIndex === 0) {
    line.setAttrs({ startShape: undefined });
  }
  if (controlIndex === controlArray.length - 1) {
    line.setAttrs({ endShape: undefined });
  }

  if (shape) {
    // 还要更新 control 的 x y
    control.position({ x: shape.x, y: shape.y });
    // 更新 line points
    updatePoints(line, control, shape.x, shape.y);

    // 更新 line startShape/endShape
    if (controlIndex === 0) {
      // line.attrs.startShape 一条直线只能连接一个图形，一个图形可以被多条线段连接
      line.setAttrs({
        startShape: {
          id: shape.id, // 当前直线连接的元素ID
          order: shape.order, // 当前元素连接的元素点位 1: 上中 2: 右中 3: 下中 4: 左中
        },
      });
    } else if (controlIndex === controlArray.length - 1) {
      line.setAttrs({
        endShape: {
          id: shape.id, // 当前直线连接的元素ID
          order: shape.order, // 当前元素连接的元素点位 1: 上中 2: 右中 3: 下中 4: 左中
        },
      });
    }
  }
}
